home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume3 / rcsit < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  22.4 KB

  1. From: talcott!topaz!packard!ihnp4!ucbvax!usc-eclc.arpa!sdcsvax!oberon!mcooper
  2. Subject: rcsit - A program to prepare files for RCS
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 61
  7. Submitted by: seismo!riacs!hplabs!sdcrdcf!uscvax!oberon!mcooper
  8.  
  9.  
  10. Appended you'll find a shar archive of a program I wrote called
  11. rcsit(1l).  I posted this program over a year ago to net.sources.
  12. After changing sites, though, I lost a copy of it and had to
  13. totally re-write it.  The new program is designed much better
  14. than the old one and seems to be much more flexible having more
  15. options.  
  16.  
  17. The program itself, does things like add rcs headers (for log
  18. tracking, version tracking, etc.) and (optionally) run rcs
  19. commands (like ci(1)) on the specified files.
  20.  
  21. Please mail me any bugs/comments that you run across.
  22.  
  23.  
  24.             Thanks,
  25.             Mike Cooper
  26. +-----------------------------------------------------------------------------+
  27. | Michael Cooper            UUCP: ...!{uscvax, sdcrdcf, engvax,          |
  28. | University Computing Services             scgvaxd, smeagol}!oberon!mcooper  |
  29. | University of Southern Cal.     BITNET: mcooper@uscvaxq, mcooper@jaxom      |
  30. | Los Angeles, Ca.   90089-0251     ARPA: mcooper@usc-oberon.arpa,          |
  31. | (213) 743-3462                mcooper@usc-eclc.arpa            |
  32. +-----------------------------------------------------------------------------+
  33. #!/bin/sh
  34. # This is a shell archive, meaning:
  35. # 1. Remove everything above the #!/bin/sh line.
  36. # 2. Save the resulting text in a file.
  37. # 3. Execute the file with /bin/sh (not csh) to create the files:
  38. #    rcsit.1
  39. #    Makefile
  40. #    rcsit.c
  41. #    _.template.c
  42. # This archive created: Tue Dec 10 13:54:54 1985
  43. # By:    Michael Cooper (University Computing Services, U.S.C.)
  44. export PATH; PATH=/bin:$PATH
  45. if test -f 'rcsit.1'
  46. then
  47.     echo shar: over-writing existing file "'rcsit.1'"
  48. fi
  49. cat << \SHAR_EOF > 'rcsit.1'
  50. ...
  51. ... $Header: rcsit.1,v 1.7 85/11/26 16:57:21 mcooper Exp $
  52. ... 
  53. ... $Log:    rcsit.1,v $
  54. ... Revision 1.7  85/11/26  16:57:21  mcooper
  55. ... Noted changes to the -t option.
  56. ... 
  57. ... Revision 1.6  85/11/11  21:20:17  mcooper
  58. ... Added AUTHOR.
  59. ... 
  60. ... Revision 1.5  85/11/11  20:13:39  mcooper
  61. ... Added description of new Fortran recognition.
  62. ... 
  63. ... Revision 1.4  85/10/27  19:18:15  mcooper
  64. ... Cleaned up table display.
  65. ... 
  66. ... Revision 1.3  85/10/27  14:55:22  mcooper
  67. ... Added description of new template feature.
  68. ... 
  69. ... Revision 1.2  85/09/28  14:22:52  mcooper
  70. ... Documented new features of checkdir (symbolic
  71. ... linking and RCSDIR).
  72. ... 
  73. ... Revision 1.1  85/09/19  15:44:22  mcooper
  74. ... Initial revision
  75. ... 
  76. ...
  77. .TH RCSIT 1l
  78. .SH NAME
  79. rcsit \- A program to prepare files for RCS
  80. .SH SYNOPSIS
  81. rcsit
  82. [
  83. .B \-chfsmM
  84. ] [
  85. .B \-qad
  86. ] [
  87. \-I\fIflags\fR
  88. ] [
  89. \-R\fIflags\fR
  90. ] [
  91. \-t\fIdirectory\fR
  92. ]
  93. .B file
  94. [
  95. .B file1, file2, ...
  96. ]
  97. .SH DESCRIPTION
  98. .I Rcsit
  99. is a semi-intelligent program to prepare files for 
  100. .I rcs(1).
  101. This
  102. involves putting the correct type of headings at the top of the file so
  103. that 
  104. .I rcs(1)
  105. will update a header and log changes in the file.
  106. .PP 
  107. By default, 
  108. .I rcsit
  109. will use default headers ``hard-wired'' into itself for each different file
  110. type that it ``knows'' about.  (See below for list of known file types).
  111. .PP
  112. If the \-t\fIdirectory\fR option is specified, then
  113. .I rcsit
  114. will use ``.template.suffix'' files
  115. (where ``suffix'' is a suffix that 
  116. .I rcsit
  117. ``knows'' about)
  118. found in 
  119. .I directory.
  120. If a directory name is not specified on the command line, then
  121. the environment variable TEMPLATES is used.
  122. If $TEMPLATES is not set, then the environment varialble, HOME is tried.
  123. .LP
  124. The following template files are recognized:
  125. .sp 2
  126. .in 10
  127. .nf
  128.  Template Name               File Type
  129.  -------------------------------------------
  130.  .template.c                 Standard C
  131.  .template.h                 C Include
  132.  .template.f                 Fortran
  133.  .template.sh                Shell Script
  134.  .template.make              Makefile
  135.  .template.man               Manual
  136. .sp 2
  137. .in -10
  138. .fi
  139. .PP
  140. .I Rcsit
  141. is ``semi-intelligent'' in that it can guess the type of headers to put in
  142. the file by the type of file (C program, C include, makefile, shell script,
  143. or manual).
  144. It determines the file type by looking at the name of the file.
  145. If the name of the file is ``Makefile'' or ``makefile'', then the
  146. file type is taken to be for 
  147. .I make(1).
  148. The suffix after the last ``.'' in the file name is then used.
  149. The following table shows the suffixes that 
  150. .I rcsit
  151. knows about:
  152. .nf
  153. .sp 2
  154. .in 10
  155. Suffix         File Type
  156. ----------------------------------------
  157. c              C Program
  158. h              C Include
  159. f              Fortran
  160. mk             \fIMake(1)\fR file
  161. sh             Shell Script
  162. csh            Shell Script
  163. [1-9]          Manual (digits 1 - 9)
  164. .fi
  165. .PP
  166. If the environement variable ``RCSDIR'' is present, then 
  167. .I rcsit
  168. will attempt to make a symbolic link from it to ``RCS'' in
  169. the current directory if the \-\fII\fR option is used and
  170. there is no directory called ``RCS'' already, in the current
  171. directory.  
  172. If the \-\fII\fR option is used and ``RCSDIR'' is not specified
  173. in the environment, then a normal directory called ``RCS'' will be
  174. created.
  175. This feature can be overrided with the \-\fId\fR option.
  176. .SH OPTIONS
  177. .TP 10
  178. .B "c"
  179. Force file type to be ``Standard C''.
  180. .TP 10
  181. .B "h"
  182. Force file type to be ``C Include''.
  183. .TP 10
  184. .B "f"
  185. Force file type to be ``Fortran''.
  186. .TP 10
  187. .B "M"
  188. Force file type to be ``Manual''.
  189. Note: If you also specify the ``I\fIflags\fR'' option,
  190. .I rcsit
  191. will run 
  192. .I rcs(1)
  193. to tell rcs what kind of comment string to use for the manual file.
  194. .TP 10
  195. .B "s"
  196. Force file type to be ``Shell Script''.
  197. .TP 10
  198. .B "m"
  199. Force file type to be ``Makefile''.  Note that this does the same thing as
  200. the -s option does.  It just prints a different message.
  201. .TP 10
  202. .B "t"
  203. Do not use any Template files for the headers.
  204. .TP 10
  205. .B "q"
  206. Be quiet.  Don't print out what is going on.  Only error messages are
  207. printed.
  208. .TP 10
  209. .B "d"
  210. Do not attempt to make the directory ``RCS''.
  211. See above for more info.
  212. .TP 10
  213. .B "a"
  214. Turn off auto guessing of file type.
  215. .TP 10
  216. .B "I\fIflags\fR"
  217. Check In file.
  218. Run RCS's 
  219. .I ci(1)
  220. on the file with ``flags'' being passed onto 
  221. .I ci(1) 
  222. as the command line arguments.
  223. .TP 10
  224. .B "R\fIflags\fR"
  225. Run 
  226. .I rcs(1)
  227. with ``flags'' as the command line arguments.
  228. .SH FILES
  229. /tmp/rcsit*    - temporary buffer
  230. .br
  231. ~/.template.*   - template files to use as the header.
  232. .br
  233. .SH AUTHOR
  234. Michael Cooper (mcooper@usc-oberon.ARPA)
  235. .SH SEE ALSO
  236. ci(1), make(1), rcs(1)
  237. .SH DIAGNOSTICS
  238. Complains about the usual stuff.  (i.e. - the specified file doesn't exist,
  239. or it can't read it...just things like that.)
  240. .SH BUGS
  241. Acts oddly in the presence of beautiful women.
  242. SHAR_EOF
  243. if test -f 'Makefile'
  244. then
  245.     echo shar: over-writing existing file "'Makefile'"
  246. fi
  247. cat << \SHAR_EOF > 'Makefile'
  248. #
  249. # $Header: Makefile,v 1.1 85/09/19 13:24:27 mcooper Exp $
  250. #
  251. # $Log:    Makefile,v $
  252. # Revision 1.1  85/09/19  13:24:27  mcooper
  253. # Initial revision
  254. #
  255. #
  256. # Makefile for rcsit.c
  257. #
  258. BIN = /u/mcooper/bin
  259. MAN = /u/mcooper/usr/man/manl/man1
  260.  
  261. rcsit: rcsit.c
  262.     cc -O -s -o rcsit rcsit.c
  263.  
  264. dbx: rcsit.c
  265.     cc -g rcsit.c
  266.  
  267. debug: rcsit.c
  268.     cc -g -DDEBUG rcsit.c
  269.  
  270. man: rcsit.1
  271.     nroff -man rcsit.1 > rcsit.man
  272.  
  273. install: rcsit rcsit.1
  274.     mv rcsit $(BIN)
  275.     cp rcsit.1 $(MAN)
  276. SHAR_EOF
  277. if test -f 'rcsit.c'
  278. then
  279.     echo shar: over-writing existing file "'rcsit.c'"
  280. fi
  281. cat << \SHAR_EOF > 'rcsit.c'
  282. /*
  283.  * $Header: rcsit.c,v 1.18 85/11/26 17:03:32 mcooper Exp $
  284.  *---------------------------------------------------------
  285.  * $Source: /u/mcooper/src/rcsit/RCS/rcsit.c,v $
  286.  * $Revision: 1.18 $
  287.  * $Date: 85/11/26 17:03:32 $
  288.  * $State: Exp $
  289.  * $Author: mcooper $
  290.  * $Locker: mcooper $
  291.  *---------------------------------------------------------
  292.  * Michael Cooper (mcooper@usc-oberon.arpa)
  293.  * University of Southern California,
  294.  * University Computing Services,
  295.  * Los Angeles, California,   90089-0251
  296.  * (213) 743-3469
  297.  *---------------------------------------------------------
  298.  *
  299.  * $Log:    rcsit.c,v $
  300.  * Revision 1.18  85/11/26  17:03:32  mcooper
  301.  * Change message telling of what header was added.
  302.  * 
  303.  * Revision 1.17  85/11/26  16:40:55  mcooper
  304.  * Changed the default -t option to FALSE.
  305.  * Added specifying directory to look for .template.*
  306.  * files in via -tdirectory.
  307.  * 
  308.  * Revision 1.16  85/11/11  21:35:34  mcooper
  309.  * Added call to access() to see if the file
  310.  * could be read.
  311.  * 
  312.  * Revision 1.15  85/11/11  21:22:33  mcooper
  313.  * Changed comment char for fortran files
  314.  * from "*" to "c".  This is what RCS uses.
  315.  * 
  316.  * Revision 1.14  85/11/11  20:08:43  mcooper
  317.  * Added descriptions for fortran (.f) files.
  318.  * 
  319.  * Revision 1.13  85/11/11  19:52:17  mcooper
  320.  * Modified default header templates to not bother specifying
  321.  * the RCS file name of the file.  co(1) worries about it.
  322.  * 
  323.  * Revision 1.12  85/10/27  19:10:07  mcooper
  324.  * Fixed bug that would not use template files if a file
  325.  * type was forced with -c, -h, etc.
  326.  * 
  327.  * Revision 1.11  85/10/27  18:48:27  mcooper
  328.  * Extended template file.  You can now have template
  329.  * files describing all the types of files that
  330.  * rcsit "knows" about.  The file $HOME/.template.*
  331.  * (where ``*'' is a ``.'' suffix rcsit can guess at or
  332.  * the type of file that is specified with an override)
  333.  * is checked for existance.  If not present, the default
  334.  * header (built into rcsit) will be used.
  335.  * 
  336.  * Revision 1.10  85/10/27  16:15:53  mcooper
  337.  * Added printing of what rcsit is doing if tflag is
  338.  * true.  Also added new headers.
  339.  * 
  340.  * Revision 1.9  85/10/27  14:47:39  mcooper
  341.  * Added new template feature.  If the file
  342.  * .template exists in the users HOME directory,
  343.  * then that file is used as the header file instead
  344.  * of the defaults for each type of file.  This can
  345.  * be disabled with the -t option in case the file
  346.  * is say a shell script.  With the template feature
  347.  * turned off, the auto guessing is re-inabled.
  348.  * Also, rcsit now removes its temporary files.
  349.  * 
  350.  * Revision 1.8  85/09/28  14:11:45  mcooper
  351.  * Added feature: if the environment variable RCSDIR is
  352.  * present, rcsit will attempt to make a symbolic
  353.  * link to the directory when the -I flag is used.
  354.  * This is done only when -I is specified AND the 
  355.  * directory RCS is not present.  You may disable this
  356.  * feature with the -d option.  Note also that if RCSDIR
  357.  * is not in the environment and the above conditions
  358.  * are true, that a normal directory called RCS will
  359.  * be created.
  360.  * 
  361.  * Revision 1.7  85/09/19  15:59:53  mcooper
  362.  * Kludge part 2 -- If you specify a ci -l of a
  363.  * man file, then the header is messed up. 
  364.  * Fix: After initializing the comment string,
  365.  * unlink the file and then run co -l.
  366.  * 
  367.  * Revision 1.6  85/09/19  15:39:57  mcooper
  368.  * Now knows about ``Manual'' type files.
  369.  * 
  370.  * Revision 1.5  85/09/19  14:23:24  mcooper
  371.  * Added lineprint() function to print things out
  372.  * nicely.  Fixed bug for Manual type files.  Due
  373.  * to the fact that RCS does not not the suffixes of
  374.  * manuals, it therefor does not know what kind of
  375.  * comment string to use.  Thus, I kludge by running
  376.  * a ``rcs -c`... ' file'' to tell rcs the comment
  377.  * string.
  378.  * 
  379.  * Revision 1.4  85/09/19  13:28:22  mcooper
  380.  * Fixed bug in auto_guess.  Would not continue through function
  381.  * when file type was ``Makefile''.
  382.  * 
  383.  * Revision 1.3  85/09/19  13:19:50  mcooper
  384.  * Added ``Shell Script'' file type.
  385.  * 
  386.  * Revision 1.2  85/09/19  10:08:36  mcooper
  387.  * Added code to run RCS commands (rcs & ci) on files.
  388.  * Fixed bug that limited number of command line files specified to
  389.  * nine.  Several other minor fixes and improvements.
  390.  * 
  391.  * Revision 1.1  85/09/17  11:33:33  mcooper
  392.  * Initial revision
  393.  * 
  394.  */
  395.  
  396. /*
  397.  * rcsit --     Prepare files for RCS.  rcsit puts the correct headings
  398.  *        at the top of files to prepare them for RCS headings
  399.  *        and log tracking.
  400.  *
  401.  * Michael Cooper    (mcooper@usc-oberon.arpa)
  402.  * University Computing Services, USC
  403.  *
  404.  * 9-16-85
  405.  */
  406.  
  407. #include <stdio.h>
  408. #include <ctype.h>
  409. #include <sys/file.h>
  410.  
  411. #ifdef NULL
  412. #undef NULL
  413. #endif
  414. #define NULL        '\0'
  415. #define LENGTH        132        /* length of line */
  416. #define TRUE        1
  417. #define FALSE        0
  418.  
  419. #ifdef DEBUG
  420.  int debugon = TRUE;
  421. #else
  422.  int debugon = FALSE;
  423. #endif
  424.  
  425. static char     *progname;        /* program name */
  426. static char     *rcsdir;
  427.  
  428. /*
  429.  * Messages to be printed for the user.
  430.  */
  431. static char    *msg_name;        
  432. static char     *m_stdc = "Standard C",
  433.         *m_include = "C Include",
  434.         *m_fortran = "Fortran",
  435.         *m_pascal = "Pascal",
  436.         *m_make    = "Makefile",
  437.         *m_shell = "Shell Script",
  438.         *m_manual = "Manual";
  439.  
  440. /*
  441.  * The headers to put at the beginning of the file(s).
  442.  * Notice that the words Header and Log do not appear here
  443.  * because RCS will put in the keyword substitutions when rcsit.c
  444.  * is co'ed.
  445.  */
  446. static char    *header;
  447. static char    *h_stdc = 
  448.     "static char *RCSid = \"$%s$\";\n\n/*\n * $%s$\n */\n\n";
  449. static char    *h_include = 
  450.     "/*\n * $%s$\n *\n * $%s$\n */\n\n";
  451. static char    *h_make =
  452.     "#\n# $%s$\n#\n# $%s$\n#\n";
  453. static char     *h_manual =
  454.     "...\n... $%s$\n... \n... $%s$\n...\n";
  455. static char     *h_fortran =
  456.     "c\nc $%s$\nc\nc $%s$\nc\n";
  457.  
  458. /*
  459.  * Template file names
  460.  */
  461. static char    *template_c     = ".template.c";    /* .c template */
  462. static char     *template_h     = ".template.h";    /* .h template */
  463. static char     *template_f     = ".template.f";    /* .f template */
  464. static char     *template_p     = ".template.p";    /* .p template */
  465. static char     *template_man     = ".template.man";    /* man template */
  466. static char    *template_make    = ".template.make";    /* make template */
  467. static char    *template_sh    = ".template.sh";    /* sh script template */
  468. static char    *tpath;                    /* path to template */
  469. static char    tfile[BUFSIZ];                /* template file */
  470. static char    tbuf[BUFSIZ];                /* current tfile */
  471.  
  472. /*
  473.  * Command line flags
  474.  */
  475. int    Iflag    = FALSE;            /* run ci(1) */
  476. int    rcsflag = FALSE;            /* run rcs(1) */
  477. int    aflag    = TRUE;                /* do auto guess */
  478. int    dflag    = TRUE;                /* creat RCS dir. */
  479. int    qflag    = FALSE;            /* be quiet! */
  480. int     cflag    = FALSE;            /* std c file */
  481. int    fflag    = FALSE;            /* fortran file */
  482. int    pflag    = FALSE;            /* pascal file */
  483. int    hflag    = FALSE;            /* include file */
  484. int    sflag    = FALSE;            /* shell script */
  485. int     mflag    = FALSE;            /* Makefile */
  486. int    Mflag    = FALSE;            /* manual */
  487. int    tflag    = FALSE;            /* template flag */
  488.  
  489. main(argc, argv)
  490. int    argc;
  491. char     *argv[];
  492. {
  493.     int x;
  494.     char    tmp[LENGTH];
  495.     char    *file;
  496.     char    *flags;
  497.     char     *tmpfile = "/tmp/rcsitXXXXXX";
  498.     char     *mktemp();
  499.     char    *gettmp();
  500.     char    *getenv();
  501.     FILE     *fd, 
  502.         *fdtmp,
  503.         *fopen();
  504.  
  505.     progname = *argv;
  506.     for (x = 1; x < argc; x++) {
  507.         if (argv[x][0] != '-')
  508.             break;
  509.         switch (argv[x][1]) {
  510.             case 'a':
  511.                 aflag = FALSE;
  512.                 break;
  513.             case 'q':
  514.                 qflag = TRUE;
  515.                 break;
  516.             case 'd':
  517.                 dflag = FALSE;
  518.                 break;
  519.             case 'f':
  520.                 fflag = TRUE;
  521.                 break;
  522.             case 'h':
  523.                 hflag = TRUE;
  524.                 break;
  525.             case 's':
  526.                 sflag = TRUE;    
  527.                 break;
  528.             case 'm':
  529.                 mflag = TRUE;
  530.                 break;
  531.             case 'M':
  532.                 Mflag = TRUE;
  533.                 break;
  534.             case 'i':
  535.             case 'I':
  536.                 Iflag = TRUE;
  537.                 flags = &argv[x][2];
  538.                 break;
  539.             case 'r':
  540.             case 'R':
  541.                 rcsflag = TRUE;
  542.                 flags = &argv[x][2];
  543.                 break;
  544.             case 't':
  545.                 tflag = TRUE;
  546.                 tpath = &argv[x][2];
  547.                 break;
  548.             case 'c':
  549.                 cflag = TRUE;
  550.                 break;
  551.             default:
  552.                 fatal("Unknown flag %s.",argv);
  553.         }
  554.     }
  555.     argc -= (x - 1);
  556.     argv += (x - 1);
  557.  
  558.     if((hflag && (mflag || Mflag || cflag)) ||
  559.         (mflag && (hflag || cflag || Mflag)) ||
  560.         (Mflag && (cflag || hflag || mflag)) ||
  561.         (cflag && (hflag || Mflag || mflag))) {
  562.             fatal("Only ONE of -c,-f,-m,-M,-h,-s may be specified.");
  563.     }
  564.     if(Iflag && rcsflag) {
  565.             fatal("Only ONE of ``-i'' and ``-r'' may be specified.");
  566.     }
  567.  
  568.     if(cflag || hflag || mflag || Mflag || fflag || sflag)
  569.         aflag = FALSE;
  570.  
  571.     if((rcsdir = getenv("RCSDIR")) == NULL)
  572.         rcsdir = "RCS";
  573.     if(Iflag && dflag)
  574.         checkdir();    /* Make RCS directory for ci */
  575.  
  576.     if((*tpath == NULL) && ((tpath = getenv("TEMPLATE")) == NULL))
  577.         if((tpath = getenv("HOME")) == NULL)
  578.             fatal("Cannot find environment variable HOME or TEMPLATE");
  579.  
  580.     /*
  581.      * make tmp file once.
  582.      */
  583.     mktemp(tmpfile);
  584.  
  585.     while (--argc) {    /* Main loop */
  586.         file = *++argv;
  587.         debug(sprintf(tmp, "...file (*++argv) = %s...", file));
  588.  
  589.         if(access(file, 4) != 0)
  590.             fatal("Cannot access %s.  No read permission OR file does not exist.",
  591.                 file);
  592.         if((fdtmp = fopen(tmpfile, "w")) == NULL) {
  593.             fatal("Cannot open tmpfile (%s).", tmpfile);
  594.         }
  595.  
  596.         if(aflag)
  597.             auto_guess(file); /* try and guess file type */
  598.         else
  599.             set_flags();      /* check and set flags */
  600.  
  601.         if(tflag) {
  602.             /*
  603.              * first get names of templates, then create
  604.              * path name to it.
  605.              */
  606.             get_temp();
  607.             sprintf(tfile, "%s/%s", tpath, tbuf);
  608.         }
  609.         if(access(tfile, 0) == 0 && tflag) {
  610.             if(!qflag || debugon)
  611.                 printf("Adding %s header file to %s...",
  612.                     msg_name, file);
  613.             copy(tfile, tmpfile, "w");
  614.             copy(file, tmpfile, "a");
  615.         } else {
  616.             if(!qflag || debugon)
  617.                 printf(
  618.                 "Adding default header (%s format) to %s...",
  619.                     msg_name, file);
  620.             /*
  621.              * put the Keywords into header string
  622.              */
  623.             sprintf(tmp, header, "Header", "Log");
  624.             fputs(tmp, fdtmp);
  625.             /*
  626.              * fclose'em, just in case.
  627.              */
  628.             fclose(fdtmp);
  629.             copy(file, tmpfile, "a");
  630.         }
  631.         unlink(file);
  632.         copy(tmpfile, file, "w");
  633.         unlink(tmpfile);
  634.  
  635.         if(!qflag || debugon)
  636.             printf("done.\n");
  637.  
  638.         if(Iflag){
  639.             rcs("ci", file, flags);
  640.             if(Mflag){    /* kludge to tell rcs about manuals */
  641.                 rcs("rcs", file, "c'... '");
  642.                 /*
  643.                  * kludge part 2 - if the user tried a ci
  644.                  * with a -l option, then the header is
  645.                  * messed up in the currently checked out
  646.                  * man file.  So we have to co the file to 
  647.                  * clean up the header.  Plus we use the
  648.                  * -l option of co to insure file locking.
  649.                  */
  650.                 if(checkfor("l", flags)){
  651.                     unlink(file);
  652.                     rcs("co", file, "l");
  653.                 }
  654.             }
  655.         }
  656.         if(rcsflag)
  657.             rcs("rcs", file, flags);
  658.     }
  659. }
  660.  
  661. /*
  662.  * debug - print (useless) debugging info.
  663.  */
  664.  
  665. debug(msg)
  666. char *msg;
  667. {
  668. #ifdef DEBUG
  669.     fprintf(stderr, msg);
  670.     putchar ('\n');
  671. #endif
  672. }
  673.  
  674. /*
  675.  * auto_guess - try and be intelligent and guess type of file
  676.  *        by looking at the suffix or the whole name
  677.  *        in the case of a makefile.
  678.  */
  679.  
  680. auto_guess(file)
  681. char    *file;
  682. {
  683.     char *suffix;
  684.     char *rindex();
  685.  
  686.     suffix = rindex(file, '.')+1;
  687.     if((strcmp(file, "makefile") == 0) || (strcmp(file, "Makefile") == 0) ||
  688.         (strcmp(suffix, "mk") == 0)) {    /* sys V std suffix */
  689.         mflag = TRUE;
  690.         sflag = FALSE;
  691.         cflag = FALSE;
  692.         hflag = FALSE;
  693.         Mflag = FALSE;
  694.         fflag = FALSE;
  695.     }
  696.     if((strcmp(suffix, "sh") == 0) || (strcmp(suffix, "csh") == 0)) {
  697.         sflag = TRUE;
  698.         cflag = FALSE;
  699.         hflag = FALSE;
  700.         mflag = FALSE;
  701.         Mflag = FALSE;
  702.         fflag = FALSE;
  703.     }
  704.     if(strcmp(suffix, "c") == 0){
  705.         cflag = TRUE;
  706.         hflag = FALSE;
  707.         mflag = FALSE;
  708.         Mflag = FALSE;
  709.         sflag = FALSE;
  710.         fflag = FALSE;
  711.     }
  712.     if(strcmp(suffix, "h") == 0){
  713.         hflag = TRUE;
  714.         cflag = FALSE;
  715.         mflag = FALSE;
  716.         Mflag = FALSE;
  717.         sflag = FALSE;
  718.         fflag = FALSE;
  719.     }
  720.     if(strcmp(suffix, "f") == 0){
  721.         fflag = TRUE;
  722.         hflag = FALSE;
  723.         cflag = FALSE;
  724.         mflag = FALSE;
  725.         Mflag = FALSE;
  726.         sflag = FALSE;
  727.     }
  728.     if(isdigit(*suffix) != 0) {
  729.         Mflag = TRUE;
  730.         hflag = FALSE;
  731.         cflag = FALSE;
  732.         mflag = FALSE;
  733.         sflag = FALSE;
  734.         fflag = FALSE;
  735.     }
  736.     set_flags();
  737.     if(!qflag || debugon)
  738.         printf("Hmm.  This file looks like a %s file.\n", msg_name);
  739. }
  740.  
  741. /*
  742.  * set_flags - set & check flags
  743.  */
  744.  
  745. set_flags()
  746. {
  747.     if(cflag || hflag || mflag || Mflag || sflag || fflag) {
  748.         if(cflag) {
  749.             msg_name = m_stdc;
  750.             header = h_stdc;
  751.         }
  752.         if(hflag) {
  753.             msg_name = m_include;
  754.             header = h_include;
  755.         }
  756.         if(mflag) {
  757.             msg_name = m_make;
  758.             header = h_make;
  759.         }
  760.         if(Mflag) {
  761.             msg_name = m_manual;
  762.             header = h_manual;
  763.         }
  764.         if(sflag) {
  765.             msg_name = m_shell;
  766.             header = h_make;
  767.         }
  768.         if(fflag) {
  769.             msg_name = m_fortran;
  770.             header = h_fortran;
  771.         }
  772.     } else {
  773.         cflag = TRUE;
  774.         set_flags();
  775.     }
  776. }
  777.  
  778. /*
  779.  * copy from -> to
  780.  */
  781.  
  782. copy(from, to, mode)
  783. char *from;
  784. char *to;
  785. char *mode;
  786. {
  787.     FILE *fdfrom, *fdto, *fopen();
  788.     char tmp[LENGTH];
  789.     char s[LENGTH];
  790.  
  791.     if((fdfrom = fopen(from, "r")) == NULL) {
  792.         fatal("Cannot open %s for reading.",from);
  793.     }
  794.     if((fdto = fopen(to, mode)) == NULL) {
  795.         fatal("Cannot open %s for \"%s\".",to,mode);
  796.     }
  797.     while(fgets(s, sizeof(s), fdfrom) != NULL)
  798.         fputs(s, fdto);
  799.     fclose(fdfrom);
  800.     fclose(fdto);
  801. }
  802.  
  803. /*
  804.  * Run RCS's rcsprog on file with flags.
  805.  */
  806.  
  807. rcs(rcsprog, file, flags)
  808. char *rcsprog;
  809. char *file;
  810. char *flags;
  811. {
  812.     char buf[LENGTH];
  813.     char tmp[LENGTH];
  814.  
  815.     if(!checkfor("q", flags) && qflag)
  816.         flags = "q";
  817.     if(strcmp(flags, NULL) == 0)
  818.         sprintf(buf, "%s %s", rcsprog, file);
  819.     else
  820.         sprintf(buf, "%s -%s %s", rcsprog, flags, file);
  821.     debug(sprintf(tmp,"Running ``%s''...\n", buf));
  822.     if(!qflag)
  823.         lineprint(sprintf(tmp, "Start of ``%s''", buf));
  824.     system(buf);
  825.     if(!qflag)
  826.         lineprint(sprintf(tmp, "End of ``%s''", buf));
  827. }
  828.  
  829. /*
  830.  * checkdir - make RCS directory if not present.
  831.  */
  832.  
  833. checkdir()
  834. {
  835.     if(access("RCS", 0) != 0){
  836.         if(!qflag || debugon)
  837.             printf("Cannot find \"RCS\" directory.  Creating...\n");
  838.         if(strcmp(rcsdir, "RCS") != 0) { 
  839.             if(symlink(rcsdir, "RCS") != 0)
  840.                 fatal("Symbolic link of %s to RCS failed.", 
  841.                     rcsdir);
  842.         } else {
  843.             if(mkdir(rcsdir, 0755) != 0)
  844.                 fatal("Cannot create \"%s\" directory.", 
  845.                     rcsdir);
  846.         }
  847.     }
  848. }
  849.  
  850. /*
  851.  * checkfor(x, str) -- check for x in str.  Return 1 (TRUE) if exists.
  852.  *            Otherwise 0 (FALSE).
  853.  */
  854.  
  855. checkfor(x, str)
  856. char     *x;
  857. char     *str;
  858. {
  859.     while(*str) {
  860.         if(strcmp(str, x) == 0)
  861.             return(TRUE);
  862.         *str++;
  863.     }
  864.     return(FALSE);
  865. }
  866.  
  867. /*
  868.  * lineprint - print msg in a nice line
  869.  */
  870.  
  871. lineprint(msg)
  872. char *msg;
  873. {
  874.     int len, left, right, x;
  875.  
  876.     len = strlen(msg);
  877.     right = (75-len)/2;
  878.     left = right;
  879.     for(x = 0; x < right; ++x)
  880.         putchar('-');
  881.     printf("[ %s ]", msg);
  882.     for(x = 0; x < left; ++x)
  883.         putchar('-');
  884.     putchar('\n');
  885. }
  886.  
  887. /*
  888.  * fatal - print error and then exit(1).
  889.  */
  890. fatal(format, str)
  891. char *format;
  892. {
  893.     static char namefmt[100];
  894.  
  895.     sprintf(namefmt, "%s: %s\n", progname, format);
  896.     _doprnt(namefmt, &str, stderr);
  897.     exit(1);
  898. }
  899.  
  900. /*
  901.  * zap str with NULL's
  902.  */
  903.  
  904. zap(str)
  905. char str[];
  906. {
  907.     int i, x;
  908.  
  909.     i = strlen(str);
  910.     for(x = 0; x <= i; )
  911.         str[x++] = NULL;
  912. }
  913.  
  914. /*
  915.  * get template names
  916.  */
  917.  
  918. get_temp()
  919. {
  920.     zap(tbuf);
  921.     if(mflag)
  922.         strcpy(tbuf, template_make);
  923.     if(Mflag)
  924.         strcpy(tbuf, template_man);
  925.     if(hflag)
  926.         strcpy(tbuf, template_h);
  927.     if(cflag)
  928.         strcpy(tbuf, template_c);
  929.     if(sflag)
  930.         strcpy(tbuf, template_sh);
  931.     if(fflag)
  932.         strcpy(tbuf, template_f);
  933. }
  934. SHAR_EOF
  935. if test -f '_.template.c'
  936. then
  937.     echo shar: over-writing existing file "'_.template.c'"
  938. fi
  939. cat << \SHAR_EOF > '_.template.c'
  940. /*
  941.  * $Header$
  942.  *------------------------------------------------------------------
  943.  *
  944.  * $Source$
  945.  * $Revision$
  946.  * $Date$
  947.  * $State$
  948.  * $Author$
  949.  * $Locker$
  950.  *
  951.  *------------------------------------------------------------------
  952.  *
  953.  * Michael Cooper (mcooper@usc-oberon.arpa)
  954.  * University Computing Services,
  955.  * University of Southern California,
  956.  * Los Angeles, California,   90089-0251
  957.  * (213) 743-3469
  958.  *
  959.  *------------------------------------------------------------------
  960.  * $Log$
  961.  *------------------------------------------------------------------
  962.  */
  963.  
  964. SHAR_EOF
  965. #    End of shell archive
  966. exit 0
  967.  
  968.